#include "schemacomponentformula.h"
#include "formula.h"

SchemaComponentFormula::SchemaComponentFormula(const string & schema_component, vector<Formula *> * formulas)
{
    if(formulas == NULL) this->formulas = NULL;
    else{
        this->formulas = new vector<Formula *>();
        for(unsigned int i=0; i<formulas->size(); i++){
            this->formulas->push_back(formulas->at(i)->clone());
        }//for
    }// if-else
    this->schema_component = schema_component;
    this->table_constraints = new map<string, vector<BooleanExpression *> * > ();
}
SchemaComponentFormula::SchemaComponentFormula(const SchemaComponentFormula & other)
{
    if(other.formulas == NULL) this->formulas = NULL;
    else{
        this->formulas = new vector<Formula *>();
        for(unsigned int i=0; i<other.formulas->size(); i++){
            this->formulas->push_back(other.formulas->at(i)->clone());
        }//for
    }// if-else
    if(other.table_constraints == NULL) this->table_constraints = NULL;
    else{
      this->table_constraints = new map<string,vector<BooleanExpression *>*>();
      map<string, vector<BooleanExpression* > * >::iterator it;
      for ( it=other.table_constraints->begin() ; it != other.table_constraints->end(); it++){
	vector<BooleanExpression*>::iterator it2;
	vector<BooleanExpression*>* bs= new vector<BooleanExpression*>();
	for ( it2=(*it).second->begin() ; it2 != (*it).second->end(); it2++){
	  bs->push_back(dynamic_cast<BooleanExpression*>((*it2)->clone()));
	}
	table_constraints->insert(pair<string,vector<BooleanExpression * > * > ((*it).first,bs));
      }
    }// if-else
    this->schema_component = other.schema_component;
}

SchemaComponentFormula::~SchemaComponentFormula()
{
	if(formulas != NULL) for(unsigned int i=0; i<formulas->size(); i++) delete formulas->at(i);
    delete formulas; formulas = NULL;

    schema_component = "";
}

vector<Formula *> * SchemaComponentFormula::getAllFormulas() const
{
    return formulas;
}

Formula * SchemaComponentFormula::getFormula(unsigned int row) const
{
    if(row >= formulas->size()) return NULL;
    return formulas->at(row);
}

vector<BooleanExpression *> * SchemaComponentFormula::getTableConstraint(string name) const
{
  return (table_constraints->find(name))->second;
}

map<string,vector<BooleanExpression*>*>* SchemaComponentFormula::getTableConstraints() const
{
  return table_constraints;
}

string SchemaComponentFormula::getSchemaComponent()
{
    return schema_component;
}

void SchemaComponentFormula::setSchemaComponent(const string & name)
{
    schema_component = name;
}

void SchemaComponentFormula::addFormula(Formula * formula)
{
    if(formulas == NULL) formulas = new vector<Formula *>();
    if(formula != NULL) formulas->push_back(formula->clone());
}

void SchemaComponentFormula::setTableConstraints(vector<BooleanExpression *>* constraints, string table)
{
  int length = constraints->size();
  
  for(int i = 0; i<length; i++)
  table_constraints->insert(make_pair<string,vector<BooleanExpression*>*>(table,constraints));
}

void SchemaComponentFormula::setTableConstraints(map<string, vector<BooleanExpression *>*>* constraintsmap){
    map<string, vector<BooleanExpression *>*>::iterator it;
    for ( it=constraintsmap->begin() ; it != constraintsmap->end(); it++){
      vector<BooleanExpression*>::iterator it2;
      vector<BooleanExpression*>* bs= new vector<BooleanExpression*>();
      for ( it2=(*it).second->begin() ; it2 != (*it).second->end(); it2++){
	bs->push_back(dynamic_cast<BooleanExpression*>((*it2)->clone()));
      }
      table_constraints->insert(pair<string,vector<BooleanExpression * > * > ((*it).first,bs));
    }
  }
void SchemaComponentFormula::setFormulas(vector<Formula *> * formulas)
{
    if(this->formulas != NULL){
        for(unsigned int i=0; i<this->formulas->size(); i++){
            delete this->formulas->at(i);
        }//for
        delete this->formulas; this->formulas = NULL;
    }//if

    if(formulas != NULL){
        this->formulas = new vector<Formula *>();
        for(unsigned int i=0; i<formulas->size(); i++){
            this->formulas->push_back(formulas->at(i)->clone());
        }//for
    }//if
}

string SchemaComponentFormula::toString()
{
  string str = "#(" + schema_component + ")={";
  map<string, vector<BooleanExpression* > * >::iterator it;
  for ( it=table_constraints->begin() ; it != table_constraints->end(); it++){
    str = str+ " Table "+ (*it).first + " constraints: {";
    vector<BooleanExpression*>::iterator it2;
    for ( it2=(*it).second->begin() ; it2 != (*it).second->end(); it2++){
      str= str + " "+ (*it2)->toString();
    }
    str = str + "}";
  }

  str=str+"}{";
  for(unsigned int i=0; i<formulas->size(); i++){
    str = str + formulas->at(i)->toString() + ",";
  }//for
  str.erase(str.length()-1);
  return str + "}";
}

unsigned int SchemaComponentFormula::size()
{
    return formulas->size();
}

SchemaComponentFormula * SchemaComponentFormula::clone()
{
    return new SchemaComponentFormula(*this);
}
